home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TPUG - Toronto PET Users Group
/
TPUG Users Group CD
/
TPUG Users Group CD.iso
/
AMIGA
/
(A)P
/
(A)P1.ADF
/
life
/
life.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-05-25
|
7KB
|
258 lines
/*
* Here is a simple LIFE program which tests the blitter operations.
* It does not extensively test the shifts or anything, but it makes
* sure that the basic interface is correct.
*/
#define HSIZE (320)
#define MODULO ((HSIZE + 15)/16)*16
#define VSIZE (190)
#define RASTSIZE (MODULO / 16 * VSIZE)
#include "structures.h"
short *a, *b, *c, *d, *e, *t1=NULL, *t2=NULL, *t3=NULL, *t4=NULL, *t5=NULL ;
short noplanes ;
struct GfxBase *GfxBase = NULL ; /* the GfxBase */
struct IntuitionBase *IntuitionBase = NULL ; /* the IntuitionBase */
struct Screen *myscreen = NULL ;
struct NewScreen mynewscreen = {
0, /* left edge */
0, /* top edge */
320, /* width */
200, /* height */
2, /* depth (change for color?)*/
1, /* detail pen */
2, /* block pen */
0, /* screen mode */
CUSTOMSCREEN, /* type */
NULL, /* use default font */
(UBYTE *)"LIFE by Tomas Rokicki", /* title */
NULL, /* initialize this gadget field */
NULL } ; /* no bitmap supplied */
/*
* This routine gets a raster for temporary storage.
*/
short *myalloc() {
void *AllocMem() ;
void *p ;
if ((p=AllocMem(2L*RASTSIZE, MEMF_CHIP | MEMF_CLEAR))==NULL) {
printf("Could not allocate raster data\n") ;
cleanup() ;
}
return(p) ;
}
/*
* Here we set things up.
*/
initialize() {
initblitdata() ;
if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary(
"intuition.library",0L))==NULL ||
(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L))
==NULL) {
printf("Couldn't open libraries.\n") ;
cleanup() ;
}
if ((myscreen = OpenScreen(&mynewscreen))==NULL) {
printf("Couldn't open screen.\n") ;
cleanup() ;
}
a = ((short *)(myscreen->BitMap.Planes[0])) + 200 ;
b = ((short *)(myscreen->BitMap.Planes[1])) + 200 ;
c = ((short *)(myscreen->BitMap.Planes[2])) + 200 ;
d = ((short *)(myscreen->BitMap.Planes[3])) + 200 ;
e = ((short *)(myscreen->BitMap.Planes[4])) + 200 ;
t1 = myalloc() ;
t2 = myalloc() ;
t3 = myalloc() ;
t4 = myalloc() ;
t5 = myalloc() ;
}
/*
* Exit routine.
*/
cleanup() {
if (myscreen != NULL)
CloseScreen(myscreen) ;
myscreen = NULL ;
if (IntuitionBase)
CloseLibrary(IntuitionBase) ;
IntuitionBase = NULL ;
if (GfxBase)
CloseLibrary(GfxBase) ;
GfxBase = NULL ;
if (t1)
FreeMem(t1, 2L*RASTSIZE) ;
if (t2)
FreeMem(t2, 2L*RASTSIZE) ;
if (t3)
FreeMem(t3, 2L*RASTSIZE) ;
if (t4)
FreeMem(t4, 2L*RASTSIZE) ;
if (t5)
FreeMem(t5, 2L*RASTSIZE) ;
exit(0) ;
}
#define PARITY (0x96)
#define CARRY (0xe8)
#define PARITY2 (0x3c)
#define CARRY2 (0xc0)
#define SPECIAL1 (0x12)
#define SPECIAL2 (0xe0)
#define COPY (0xf0)
/*
* Does one LIFE generation. Fancy algorithm uses only 10 blits. If
* anyone can improve this, please let me know.
*/
dogeneration() {
OwnBlitter() ;
/*
* Take horizontal sums.
*/
blit(a, 0, 1,
a, 2, 1,
a, 1, 1,
t1, 1, 1,
MODULO, HSIZE-2, VSIZE-2, PARITY) ;
blit(a, 0, 1,
a, 2, 1,
a, 1, 1,
t2, 1, 1,
MODULO, HSIZE-2, VSIZE-2, CARRY) ;
/*
* Take sums for middle row.
*/
blit(a, 0, 1,
a, 2, 1,
a, 1, 1,
t3, 1, 1,
MODULO, HSIZE-2, VSIZE-2, PARITY2) ;
blit(a, 0, 1,
a, 2, 1,
a, 1, 1,
t4, 1, 1,
MODULO, HSIZE-2, VSIZE-2, CARRY2) ;
/*
* Now, sum each of the three columns.
*/
blit(t1, 1, 0,
t1, 1, 2,
t3, 1, 1,
t5, 1, 1,
MODULO, HSIZE-2, VSIZE-2, PARITY) ;
blit(t1, 1, 0,
t1, 1, 2,
t3, 1, 1,
t3, 1, 1,
MODULO, HSIZE-2, VSIZE-2, CARRY) ;
blit(t2, 1, 0,
t2, 1, 2,
t4, 1, 1,
t1, 1, 1,
MODULO, HSIZE-2, VSIZE-2, PARITY) ;
blit(t2, 1, 0,
t2, 1, 2,
t4, 1, 1,
t4, 1, 1,
MODULO, HSIZE-2, VSIZE-2, CARRY) ;
/*
* Now, check high two order bits, then combine with original and
* low order bit.
*/
blit(t1, 1, 1,
t4, 1, 1,
t3, 1, 1,
t2, 1, 1,
MODULO, HSIZE-2, VSIZE-2, SPECIAL1) ;
/*
* Before we do the final write, we copy bits down one generation.
*/
switch (noplanes) {
case 5:
blit(d, 1, 1,
d, 1, 1,
d, 1, 1,
e, 1, 1,
MODULO, HSIZE-2, VSIZE-2, COPY) ;
case 4:
blit(c, 1, 1,
c, 1, 1,
c, 1, 1,
d, 1, 1,
MODULO, HSIZE-2, VSIZE-2, COPY) ;
case 3:
blit(b, 1, 1,
b, 1, 1,
b, 1, 1,
c, 1, 1,
MODULO, HSIZE-2, VSIZE-2, COPY) ;
case 2:
blit(a, 1, 1,
a, 1, 1,
a, 1, 1,
b, 1, 1,
MODULO, HSIZE-2, VSIZE-2, COPY) ;
default: ;
}
blit(t2, 1, 1,
t5, 1, 1,
a, 1, 1,
a, 1, 1,
MODULO, HSIZE-2, VSIZE-2, SPECIAL2) ;
DisownBlitter() ;
}
/*
* Random number generator; probably not a very good one.
*/
int rnd(i)
int i ;
{
static long seed = 323214521 ;
long rval ;
seed = seed * 123213 + 121 ;
rval = (seed >> 5) & 65535 ;
return ((i * rval) >> 16) ;
}
/*
* Main routine. If called with no arguments, makes 1 bit plane screen.
* Otherwise, first argument is used as the number of bit planes.
*/
main (argc, argv)
int argc ;
char *argv[] ;
{
register int i ;
register int x, y ;
long t1[3], t2[3] ;
if (argc < 2 || sscanf(argv[1], "%d", &noplanes) < 1 || noplanes < 1
|| noplanes > 5)
noplanes = 1 ;
mynewscreen.Depth = noplanes ;
initialize() ;
for (i=0; i<RASTSIZE; i++)
a[i] = 0 ;
a[2010] = 0x0060 ;
a[2030] = 0x00c0 ;
a[2050] = 0x0040 ;
i = 0 ;
DateStamp(t1) ;
x = 12 ;
while (x != 0 || y != 100) {
x = rnd(HSIZE-2) + 1 ;
y = rnd(VSIZE-2) + 1 ;
a[y*20+(x>>4)] |= 1 << (15 - (x & 15)) ;
dogeneration() ;
i++ ;
x = myscreen->MouseX ;
y = myscreen->MouseY ;
}
DateStamp(t2) ;
printf("%ld ticks %d generations\n",
t2[2]-t1[2] +
(t2[1]-t1[1]) * 3000L +
(t2[0]-t1[0]) * 4320000L, i) ;
printf("Done.\n") ;
cleanup() ;
}